package com.alibaba.citrus.ots.sales.plan.facade.service.salesplan.adjust;

import com.alibaba.citrus.ots.common.annotation.FacadeInvoker;
import com.alibaba.citrus.ots.common.exception.FacadeException;
import com.alibaba.citrus.ots.sales.plan.api.salesplan.SalesPlanQueryService;
import com.alibaba.citrus.ots.sales.plan.api.salesplan.adjust.SalesPlanAdjustDetailQueryService;
import com.alibaba.citrus.ots.sales.plan.dto.api.request.PageQueryPlanAdjustDetailRequest;
import com.alibaba.citrus.ots.sales.plan.dto.api.request.QuerySalesPlanRequest;
import com.alibaba.citrus.ots.sales.plan.dto.api.request.SalesPlanAdjustDetailSubTotalRequest;
import com.alibaba.citrus.ots.sales.plan.dto.api.response.SalesPlanAdjustDetailSubTotalResponse;
import com.alibaba.citrus.ots.sales.plan.facade.service.SalesPlanOutCommonService;
import com.alibaba.citrus.ots.sales.plan.model.enums.SalesStatBizTypeEnum;
import com.alibaba.citrus.ots.sales.plan.repository.SalesPlanAdjustDetailRepository;
import com.alibaba.citrus.ots.sales.plan.sdo.SalesPlanAdjustDetailSDO;
import com.alibaba.citrus.ots.sales.plan.sdo.SalesPlanSDO;
import com.alibaba.cz.base.tool.StringUtil;
import com.alibaba.cz.base.tool.log.Log;
import com.alibaba.cz.base.tool.page.PageResult;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.lattice2.epoch.sdk.model.Result;
import com.epoch.app.bcots.model.dto.PageQuerySalesPlanAdjustDetailRequest;
import com.epoch.app.bcots.model.dto.PageQuerySalesPlanAdjustDetailResponse;
import com.epoch.app.bcots.model.dto.ScItemSDO;
import com.epoch.app.bcots.service.SalesPlanService;
import com.epoch.app.otsplatformenhance.model.dto.CustomerAddressIndex;
import com.epoch.app.otsunifiedinventory.model.dto.GetStoreInventoryAggreRequest;
import com.epoch.app.otsunifiedinventory.model.dto.WarehouseInventory;
import com.epoch.app.otsunifiedinventory.service.OtsUnifiedInventoryService;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * @author yuhailin
 * @description:
 * @date 2021-10-25 16:17
 */
@Service
public class SalesPlanAdjustDetailQueryServiceImpl implements SalesPlanAdjustDetailQueryService {
    Log log = Log.getLogger(SalesPlanAdjustDetailQueryServiceImpl.class);

    @Resource
    private SalesPlanAdjustDetailRepository salesPlanAdjustDetailRepository;

    @Autowired(required = false)
    private OtsUnifiedInventoryService otsUnifiedInventoryService;

    @Resource
    private SalesPlanOutCommonService salesPlanOutCommonService;

    @Resource
    private SalesPlanService salesPlanService;

    @Resource
    private SalesPlanQueryService salesPlanQueryService;

    @Override
    @FacadeInvoker
    public Result<PageResult<List<SalesPlanAdjustDetailSDO>>> pageQuerySalesPlanAdjustDetailList(PageQueryPlanAdjustDetailRequest pageQueryPlanAdjustDetailRequest) {
        if (pageQueryPlanAdjustDetailRequest.getBizType() == null && StringUtil.isBlank(pageQueryPlanAdjustDetailRequest.getBizId())) {
            throw new FacadeException("OTS-02-002-02-15-007");
        }
        SalesStatBizTypeEnum byOrganizationType = SalesStatBizTypeEnum.getByOrganizationType(pageQueryPlanAdjustDetailRequest.getBizType());
        if (byOrganizationType == null) {
//            throw new FacadeException("OTS-02-002-02-15-007");
            //查询月度计划，获取业务单元id
            QuerySalesPlanRequest querySalesPlanRequest = new QuerySalesPlanRequest();
            querySalesPlanRequest.setId(pageQueryPlanAdjustDetailRequest.getPlanId());
            Result<SalesPlanSDO> result = salesPlanQueryService.getSalesPlan(querySalesPlanRequest);
            if (!result.isSuccess() || null == result.getResult()) {
                log.info("subTotalSalesPlanAdjustDetail月度计划{}不存在", pageQueryPlanAdjustDetailRequest.getPlanId());
                throw new FacadeException("OTS-02-002-00-16-001");
            }
            String orgBusinessUnitCode = result.getResult().getOrgBusinessUnitCode();
            if (StringUtil.isBlank(orgBusinessUnitCode)) {
                log.info("subTotalSalesPlanAdjustDetail月度计划{}缺少业务单位编码", pageQueryPlanAdjustDetailRequest.getPlanId());
                throw new FacadeException("OTS-02-002-00-16-002");
            }
            byOrganizationType = SalesStatBizTypeEnum.BUSINESS_UNIT;
            pageQueryPlanAdjustDetailRequest.setBizId(orgBusinessUnitCode);
            pageQueryPlanAdjustDetailRequest.setBizType(103);
        }
        switch (byOrganizationType) {
            case SALESMAN:
                pageQueryPlanAdjustDetailRequest.setManageEmployeeId(pageQueryPlanAdjustDetailRequest.getBizId());
                break;
            case SALES_DEPARTMENT:
                pageQueryPlanAdjustDetailRequest.setOrgSalesDepartmentCode(pageQueryPlanAdjustDetailRequest.getBizId());
                break;
            case SALES_CHANNEL:
                pageQueryPlanAdjustDetailRequest.setOrgSalesChannelCode(pageQueryPlanAdjustDetailRequest.getBizId());
                break;
            case SALES_ORGANIZATION:
                pageQueryPlanAdjustDetailRequest.setOrgSalesOrganizationCode(pageQueryPlanAdjustDetailRequest.getBizId());
                break;
            case BUSINESS_UNIT:
                pageQueryPlanAdjustDetailRequest.setOrgBusinessUnitCode(pageQueryPlanAdjustDetailRequest.getBizId());
                break;
            default:
        }
        PageResult<List<SalesPlanAdjustDetailSDO>> salesPlanAdjustDetailList = salesPlanAdjustDetailRepository.pageQuerySalesPlanAdjustDetailList(pageQueryPlanAdjustDetailRequest);
        if (null != salesPlanAdjustDetailList && null != salesPlanAdjustDetailList.getContent() && salesPlanAdjustDetailList.getContent().size() > 0) {
            pageResultConverter(salesPlanAdjustDetailList);
        }
        return Result.success(salesPlanAdjustDetailList);
    }

    private void pageResultConverter(PageResult<List<SalesPlanAdjustDetailSDO>> salesPlanAdjustDetailList) {
        Set<String> scItemSet = Sets.newHashSet();
        Set<String> customerAddressSet = Sets.newHashSet();
        Set<String> customerSet = Sets.newHashSet();
        Set<String> orgSalesOrganizationCodeSet = Sets.newHashSet();
        Set<String> channelCodeSet = Sets.newHashSet();
        salesPlanAdjustDetailList.getContent().forEach(salesPlanLineSDO -> {
            scItemSet.add(salesPlanLineSDO.getScItemId());
            customerAddressSet.add(salesPlanLineSDO.getCustomerAddress());
            customerSet.add(salesPlanLineSDO.getCustomerCode());
            orgSalesOrganizationCodeSet.add(salesPlanLineSDO.getOrgSalesOrganizationCode());
            channelCodeSet.add(salesPlanLineSDO.getChannelCode());
        });
        //获取货品外部编码
//        Set<String> scItemSet = salesPlanAdjustDetailList.getContent().stream().map(SalesPlanAdjustDetailSDO::getScItemId).collect(Collectors.toSet());
        Map<String, ScItemSDO> scItemMapByOutMap = salesPlanOutCommonService.getScItemMapByIds(scItemSet, false);
        if (null == scItemMapByOutMap){
            log.error("SalesPlanAdjustDetailQueryServiceImpl.pageResultConverter scItemMapByOutMap is null, scItemSet=" + scItemSet);
            return;
        }
        Map<String, CustomerAddressIndex> customerAddressByFive = salesPlanOutCommonService.getCustomerAddressByFive(customerAddressSet, customerSet, orgSalesOrganizationCodeSet, channelCodeSet, null);
        if (null == customerAddressByFive){
            log.error("SalesPlanAdjustDetailQueryServiceImpl.pageResultConverter customerAddressByFive is null, customerAddress=" + customerAddressSet + ", customerSet=" + customerSet + ", orgSet=" + orgSalesOrganizationCodeSet);
            return;
        }
        List<String> addressIdCollect = customerAddressByFive.values().stream().map(index -> {
            return Objects.toString(index.getId());
        }).collect(Collectors.toList());
        //取门店库存
        GetStoreInventoryAggreRequest getStoreInventoryAggreRequest = new GetStoreInventoryAggreRequest();
        getStoreInventoryAggreRequest.setAddressCodeList(addressIdCollect);
        getStoreInventoryAggreRequest.setGoodsIds(Lists.newArrayList(scItemSet));
        Map<String, WarehouseInventory> businessInventoryMap = Maps.newHashMap();
        try {
            Result<List<WarehouseInventory>> listResult = otsUnifiedInventoryService.getStoreInventoryAggre(getStoreInventoryAggreRequest);
            if (listResult != null && listResult.isSuccess() && CollectionUtils.isNotEmpty(listResult.getResult())){
                businessInventoryMap = listResult.getResult()
                        .stream().collect(Collectors.toMap(x -> x.getGoodsId() + x.getAddressCode(), a -> a, (a, b) -> a));
            }
        }catch (Exception e){
            log.error("SalesPlanAdjustDetailQueryServiceImpl.searchBusinessInventoryByPage.exception:{}",e);
        }

        Map<String, WarehouseInventory> finalBusinessInventoryMap = businessInventoryMap;
        for (SalesPlanAdjustDetailSDO salesPlanAdjustDetailSDO : salesPlanAdjustDetailList.getContent()) {
            salesPlanAdjustDetailSDO.setInventory(0);
            if (!Objects.isNull(scItemMapByOutMap) && !scItemMapByOutMap.isEmpty()) {
                ScItemSDO scItemSDO = scItemMapByOutMap.get(salesPlanAdjustDetailSDO.getScItemId());
                if (Objects.nonNull(scItemSDO)) {
                    //外部编码
                    salesPlanAdjustDetailSDO.setOuterId(scItemSDO.getOuterId());
                }
            }
            CustomerAddressIndex customerAddressIndex = customerAddressByFive.get(salesPlanAdjustDetailSDO.getCustomerCode() + salesPlanAdjustDetailSDO.getCustomerAddress() + salesPlanAdjustDetailSDO.getOrgSalesOrganizationCode() + salesPlanAdjustDetailSDO.getChannelCode());
            if (customerAddressIndex == null) {
                salesPlanAdjustDetailSDO.setInventoryStr("0");
                continue;
            }
            WarehouseInventory warehouseInventory = finalBusinessInventoryMap.get(salesPlanAdjustDetailSDO.getScItemId() + customerAddressIndex.getId());
            if (Objects.nonNull(warehouseInventory)) {
                salesPlanAdjustDetailSDO.setInventoryStr(warehouseInventory.getAvailableQuantityFormat());
            } else {
                salesPlanAdjustDetailSDO.setInventoryStr("0");
            }
        }
    }

    @Override
    @FacadeInvoker
    public Result<SalesPlanAdjustDetailSubTotalResponse> subTotalSalesPlanAdjustDetail(SalesPlanAdjustDetailSubTotalRequest salesPlanAdjustDetailSubTotalRequest) {
        if (salesPlanAdjustDetailSubTotalRequest.getBizType() == null && StringUtil.isBlank(salesPlanAdjustDetailSubTotalRequest.getBizId())) {
            throw new FacadeException("OTS-02-002-02-15-007");
        }
        SalesStatBizTypeEnum byOrganizationType = SalesStatBizTypeEnum.getByOrganizationType(salesPlanAdjustDetailSubTotalRequest.getBizType());
        if (byOrganizationType == null) {
//            throw new FacadeException("OTS-02-002-02-15-007");
            //查询月度计划，获取业务单元id
            QuerySalesPlanRequest querySalesPlanRequest = new QuerySalesPlanRequest();
            querySalesPlanRequest.setId(salesPlanAdjustDetailSubTotalRequest.getPlanId());
            Result<SalesPlanSDO> result = salesPlanQueryService.getSalesPlan(querySalesPlanRequest);
            if (!result.isSuccess() || null == result.getResult()) {
                log.info("subTotalSalesPlanAdjustDetail月度计划{}不存在", salesPlanAdjustDetailSubTotalRequest.getPlanId());
                throw new FacadeException("OTS-02-002-00-16-001");
            }
            String orgBusinessUnitCode = result.getResult().getOrgBusinessUnitCode();
            if (StringUtil.isBlank(orgBusinessUnitCode)) {
                log.info("subTotalSalesPlanAdjustDetail月度计划{}缺少业务单位编码", salesPlanAdjustDetailSubTotalRequest.getPlanId());
                throw new FacadeException("OTS-02-002-00-16-002");
            }
            byOrganizationType = SalesStatBizTypeEnum.BUSINESS_UNIT;
            salesPlanAdjustDetailSubTotalRequest.setBizId(orgBusinessUnitCode);
            salesPlanAdjustDetailSubTotalRequest.setBizType(103);
        }
        switch (byOrganizationType) {
            case SALESMAN:
                salesPlanAdjustDetailSubTotalRequest.setManageEmployeeId(salesPlanAdjustDetailSubTotalRequest.getBizId());
                break;
            case SALES_DEPARTMENT:
                salesPlanAdjustDetailSubTotalRequest.setOrgSalesDepartmentCode(salesPlanAdjustDetailSubTotalRequest.getBizId());
                break;
            case SALES_CHANNEL:
                salesPlanAdjustDetailSubTotalRequest.setOrgSalesChannelCode(salesPlanAdjustDetailSubTotalRequest.getBizId());
                break;
            case SALES_ORGANIZATION:
                salesPlanAdjustDetailSubTotalRequest.setOrgSalesOrganizationCode(salesPlanAdjustDetailSubTotalRequest.getBizId());
                break;
            case BUSINESS_UNIT:
                salesPlanAdjustDetailSubTotalRequest.setOrgBusinessUnitCode(salesPlanAdjustDetailSubTotalRequest.getBizId());
                break;
            default:
        }
        return Result.success(salesPlanAdjustDetailRepository.subTotalSalesPlanAdjustDetail(salesPlanAdjustDetailSubTotalRequest));
    }

    @Override
    @FacadeInvoker
    public Result<BigDecimal> queryCompletePercent(SalesPlanAdjustDetailSubTotalRequest salesPlanAdjustDetailSubTotalRequest) {
        if (salesPlanAdjustDetailSubTotalRequest.getBizType() == null && StringUtil.isBlank(salesPlanAdjustDetailSubTotalRequest.getBizId())) {
            throw new FacadeException("OTS-02-002-02-15-007");
        }
        SalesStatBizTypeEnum byOrganizationType = SalesStatBizTypeEnum.getByOrganizationType(salesPlanAdjustDetailSubTotalRequest.getBizType());
        if (byOrganizationType == null) {
            throw new FacadeException("OTS-02-002-02-15-007");
        }
        switch (byOrganizationType) {
            case SALESMAN:
                salesPlanAdjustDetailSubTotalRequest.setManageEmployeeId(salesPlanAdjustDetailSubTotalRequest.getBizId());
                break;
            case SALES_DEPARTMENT:
                salesPlanAdjustDetailSubTotalRequest.setOrgSalesDepartmentCode(salesPlanAdjustDetailSubTotalRequest.getBizId());
                break;
            case SALES_CHANNEL:
                salesPlanAdjustDetailSubTotalRequest.setOrgSalesChannelCode(salesPlanAdjustDetailSubTotalRequest.getBizId());
                break;
            case SALES_ORGANIZATION:
                salesPlanAdjustDetailSubTotalRequest.setOrgSalesOrganizationCode(salesPlanAdjustDetailSubTotalRequest.getBizId());
                break;
            case BUSINESS_UNIT:
                salesPlanAdjustDetailSubTotalRequest.setOrgBusinessUnitCode(salesPlanAdjustDetailSubTotalRequest.getBizId());
                break;
            default:
        }
        return Result.success(salesPlanAdjustDetailRepository.queryCompletePercent(salesPlanAdjustDetailSubTotalRequest));
    }

    @Override
    @FacadeInvoker
    public PageQuerySalesPlanAdjustDetailResponse getSalesPlanAdjustDetailList(PageQuerySalesPlanAdjustDetailRequest pageQuerySalesPlanAdjustDetailRequest) {
        PageQuerySalesPlanAdjustDetailResponse response = PageQuerySalesPlanAdjustDetailResponse.builder().result(Lists.newArrayList()).build();
        try {
            if (pageQuerySalesPlanAdjustDetailRequest == null) {
                return response;
            }
            response = salesPlanService.pageQuerySalesPlanAdjustDetail(pageQuerySalesPlanAdjustDetailRequest);
            log.info("getSalesPlanAdjustDetailList:" + JSONObject.toJSONString(response));
            Integer total = response.getTotal();
            List result = response.getResult();
            if (!response.getSuccess() || CollectionUtils.isEmpty(result) || total == 0) {
                return response;
            }
            result = Lists.newArrayList();
            int totalPage = total % 100 == 0 ? total / 100 : total / 100 + 1;
            for (int i = 0; i < totalPage; i++) {
                pageQuerySalesPlanAdjustDetailRequest.setStart(i * 100);
                PageQuerySalesPlanAdjustDetailResponse listResponse = salesPlanService.pageQuerySalesPlanAdjustDetail(pageQuerySalesPlanAdjustDetailRequest);
                if (listResponse.getSuccess() && CollectionUtils.isNotEmpty(listResponse.getResult()) && listResponse.getTotal() != 0) {
                    result.addAll(listResponse.getResult());
                }
            }
            response.setResult(result);
            log.info("getSalesPlanAdjustDetailList:" + response.getResult().size());
            return response;
        } catch (Exception e) {
            log.info("月度计划调整明细汇总导出异常" + JSONObject.toJSONString(e));
            return PageQuerySalesPlanAdjustDetailResponse.builder().result(Lists.newArrayList()).build();
        }
    }
}
